package com.storage.system.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.storage.common.core.domain.ServiceResponse;
import com.storage.common.core.page.TableDataInfo;
import com.storage.common.core.text.Convert;
import com.storage.common.enums.*;
import com.storage.common.jpush.JiGuangPushUtil;
import com.storage.common.utils.GsonUtil;
import com.storage.system.domain.*;
import com.storage.system.mapper.*;
import com.storage.system.service.IStorageProcurementOrderService;
import com.storage.system.utils.GoodsConvertUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 采购/订购 订单 服务层实现
 *
 * @author ruoyi
 * @date 2019-08-26
 */
@Service
public class StorageProcurementOrderServiceImpl implements IStorageProcurementOrderService {

    private static final Logger logger = LoggerFactory.getLogger(StorageProcurementOrderServiceImpl.class);

    @Autowired
    private StorageProcurementOrderMapper storageProcurementOrderMapper;

    @Autowired
    private StorageUserMapper storageUserMapper;

    @Autowired
    private StorageGoodsMapper storageGoodsMapper;

    @Autowired
    private StorageUserAgentMapper storageUserAgentMapper;

    @Autowired
    private StorageProductMapper storageProductMapper;

    @Autowired
    private StorageShopMapper storageShopMapper;

    @Autowired
    private StorageAccountRecordMapper storageAccountRecordMapper;

    @Autowired
    private StorageImageMapper storageImageMapper;

    @Autowired
    private StorageNoticeMessageMapper storageNoticeMessageMapper;

    /**
     * 查询采购/订购 订单信息
     *
     * @param id 采购/订购 订单ID
     * @return 采购/订购 订单信息
     */
    @Override
    public StorageProcurementOrder selectStorageProcurementOrderById(Long id) {
        return storageProcurementOrderMapper.selectStorageProcurementOrderById(id);
    }

    /**
     * 查询采购/订购 订单列表
     *
     * @param storageProcurementOrder 采购/订购 订单信息
     * @return 采购/订购 订单集合
     */
    @Override
    public ServiceResponse<TableDataInfo> selectStorageProcurementOrderList(StorageUser currUser, StorageProcurementOrder storageProcurementOrder, Integer pageNum, Integer pageSize) {

        if (pageNum == null) {
            pageNum = 1;
        }
        if (pageSize == null) {
            pageSize = 10;
        }

        Integer start = (pageNum - 1) * pageSize;

        // 查询查询分页数据
        List<StorageProcurementOrder> procurementOrders = storageProcurementOrderMapper.queryPageList(storageProcurementOrder, start, pageSize);
        // 查询totalCount
        Long totalCount = storageProcurementOrderMapper.queryPageCount(storageProcurementOrder);

        procurementOrders.stream().forEach(item -> wrapper(item));
        TableDataInfo pageList = new TableDataInfo(procurementOrders, totalCount, pageNum, pageSize);
        return new ServiceResponse<>(true, pageList, null);
    }

    /**
     * 组装数据
     *
     * @param item
     */
    private void wrapper(StorageProcurementOrder item) {
        if (item.getProducts() == null) {
            item.setProducts(new ArrayList<>());
        }
        // 如果当前订单申请人是店铺申请的那么将店铺信息查询出来
        if (item.getApplicationType() == OwnerType.SHOP.getValue()) {
            StorageShop shop = storageShopMapper.selectStorageShopById(item.getApplicationUserId());
            item.setShop(shop);
        }

        if (item.getProvideUserId() != null) {
            StorageUser provideUser = storageUserMapper.selectStorageUserById(item.getProvideUserId());
            item.setProvideUserName(provideUser.getNickName());
        }

        Gson gson = GsonUtil.getGson();
        List<StorageProduct> storageProducts = gson.fromJson(item.getGoodsContent(), new TypeToken<List<StorageProduct>>() {
        }.getType());
        if (storageProducts == null || storageProducts.size() == 0) {
            return;
        }

        for (StorageProduct product : storageProducts) {
            if (product.getGoods() == null || product.getGoods().size() == 0) {
                continue;
            }
            GoodsConvertUtils.convert(product);
            item.getProducts().add(product);
        }
    }

    /**
     * 修改采购/订购 订单
     * 修改点
     * 1.下级发起采货申请  -   上级同意以后对应库存数量立即减掉
     * 2.上级发货        -    上级商品库存立即减掉
     * <p>
     * 3.下级同意以后 则对下级货物进行入库
     * 4.下级不同意  则将订单中上级扣减掉的商品数据量还原
     *
     * @param storageProcurementOrder 采购/订购 订单信息
     * @return 结果
     */
    @Override
    public ServiceResponse<StorageProcurementOrder> updateStorageProcurementOrder(StorageUser currUser, StorageProcurementOrder storageProcurementOrder) {
        StorageUser providerUser = null;
        StorageUser applicationUser = null;
        String title = null;
        StorageNoticeMessage noticeMessage = null;
        if (storageProcurementOrder.getId() != null) {

            OrderType type = OrderType.valueOf(storageProcurementOrder.getOrderStatus());
            StorageProcurementOrder oldOrder = null;

            switch (type) {
                case START_ORDER:
                    break;
                case PROVIDER_ACCEPT:
                    // 查询最新订单 from db
                    oldOrder = storageProcurementOrderMapper.selectStorageProcurementOrderById(storageProcurementOrder.getId());
                    oldOrder.setActualPaymentAmount(storageProcurementOrder.getActualPaymentAmount());
                    if (oldOrder.getActualPaymentAmount() == null) {
                        oldOrder.setActualPaymentAmount(new BigDecimal(0));
                    }

                    oldOrder.setOrderStatus(type.getValue());

                    // 当前被采购方确定完成 - 将被采购方对应的库存数据量减去采购的数据量
                    ServiceResponse<Boolean> reduceResponse = reduceOrderGoodsNumberFromProvider(oldOrder);
                    if (!reduceResponse.isSuccess()) {
                        return new ServiceResponse<>(false, oldOrder, reduceResponse.getError());
                    }

                    if (oldOrder.getApplicationType() == OwnerType.SHOP.getValue()) {
                        applicationUser = storageUserMapper.selectStorageUserByShopIdRole(oldOrder.getApplicationUserId(), RoleType.SHOW_LEADER.getValue());
                    } else if (oldOrder.getApplicationType() == OwnerType.AGENT.getValue()) {
                        applicationUser = storageUserMapper.selectStorageUserById(oldOrder.getApplicationUserId());
                    }

                    if (applicationUser != null) {
                        // 给采购方推送被采购方确认订单成功极光推送
                        title = String.format("你发起的采购申请已通过, 等待您对订单再次进行确认,请前往查看", oldOrder.getOrderCode());
                        noticeMessage = new StorageNoticeMessage(applicationUser.getId(), applicationUser.getPhone(), oldOrder.getGoodsContent(), title);
                        storageNoticeMessageMapper.insertStorageNoticeMessage(noticeMessage);
                        sendNotice(oldOrder, applicationUser.getPhone(), title, oldOrder.getGoodsContent(), noticeMessage.getId());
                    }
                    break;
                case APPLICATION_ACCEPT:
                    break;
                case PROVIDER_REFUSE:
                    // 查询最新订单 from db
                    oldOrder = storageProcurementOrderMapper.selectStorageProcurementOrderById(storageProcurementOrder.getId());

                    if (oldOrder.getApplicationType() == OwnerType.SHOP.getValue()) {
                        applicationUser = storageUserMapper.selectStorageUserByShopIdRole(oldOrder.getApplicationUserId(), RoleType.SHOW_LEADER.getValue());
                    } else if (oldOrder.getApplicationType() == OwnerType.AGENT.getValue()) {
                        applicationUser = storageUserMapper.selectStorageUserById(oldOrder.getApplicationUserId());
                    }

                    if (applicationUser != null) {
                        title = String.format("您发起的采购申请订单已被上级供货方拒绝,订单号：%s,请前往查看", oldOrder.getOrderCode());
                        noticeMessage = new StorageNoticeMessage(applicationUser.getId(), applicationUser.getPhone(), oldOrder.getGoodsContent(), title);
                        storageNoticeMessageMapper.insertStorageNoticeMessage(noticeMessage);
                        sendNotice(oldOrder, applicationUser.getPhone(), title, oldOrder.getGoodsContent(), noticeMessage.getId());
                    }

                    break;
                case APPLICATION_REFUSE:
                    // 下级不同意  则将订单中上级扣减掉的商品数据量还原
                    // 查询最新订单 from db
                    oldOrder = storageProcurementOrderMapper.selectStorageProcurementOrderById(storageProcurementOrder.getId());
                    if (storageProcurementOrder == null) {
                        return new ServiceResponse<>(false, null, "订单不存在");
                    }

                    ServiceResponse<Boolean> revokeResponse = revokeProviderStockNum(oldOrder);
                    if (!revokeResponse.isSuccess()) {
                        return new ServiceResponse<>(false, null, revokeResponse.getError());
                    }

                    // 给被采购方插入系统消息并极光推送
                    providerUser = storageUserMapper.selectStorageUserById(oldOrder.getProvideUserId());
                    if (providerUser == null) {
                        return new ServiceResponse<>(false, null, "被采购方账号不存在,请核实重新发起采购");
                    }

                    title = String.format("下级发起的采购申请订单号：%s 采购方再次确认时候已被下级拒绝,请前往查看", oldOrder.getOrderCode());
                    noticeMessage = new StorageNoticeMessage(providerUser.getId(), providerUser.getPhone(), oldOrder.getGoodsContent(), title);
                    storageNoticeMessageMapper.insertStorageNoticeMessage(noticeMessage);
                    sendNotice(oldOrder, providerUser.getPhone(), title, oldOrder.getGoodsContent(), noticeMessage.getId());
                    break;
                case ORDER_SUCCESS:
                    // 查询最新订单 from db
                    oldOrder = storageProcurementOrderMapper.selectStorageProcurementOrderById(storageProcurementOrder.getId());
                    if (storageProcurementOrder == null) {
                        return new ServiceResponse<>(false, null, "订单不存在");
                    }

                    // 计算采购方和供货方的账目情况
                    ServiceResponse<Boolean> calculateResponse = calculateMoney(currUser, oldOrder);
                    if (!calculateResponse.isSuccess()) {
                        return new ServiceResponse<>(false, oldOrder, calculateResponse.getError());
                    }

                    // 当前订单最终确定完成 - 自动将采购方采购的商品入库
                    autoInsertProcurementUserStock(currUser, oldOrder);

                    // 给被采购方插入系统消息并极光推送
                    providerUser = storageUserMapper.selectStorageUserById(oldOrder.getProvideUserId());
                    if (providerUser == null) {
                        return new ServiceResponse<>(false, null, "被采购方账号不存在,请核实重新发起采购");
                    }

                    title = String.format("下级发起的采购申请订单号：%s 已最终确认成功,请前往查看", oldOrder.getOrderCode());
                    noticeMessage = new StorageNoticeMessage(providerUser.getId(), providerUser.getPhone(), oldOrder.getGoodsContent(), title);
                    storageNoticeMessageMapper.insertStorageNoticeMessage(noticeMessage);
                    sendNotice(oldOrder, providerUser.getPhone(), title, oldOrder.getGoodsContent(), noticeMessage.getId());
                    break;
                default:
            }
            // 更新订单状态
            storageProcurementOrderMapper.updateStorageProcurementOrder(storageProcurementOrder);
        } else {
            // 生成订单编号
            storageProcurementOrder.setOrderCode(getOrderCode());
            if (storageProcurementOrder.getOrderStatus() == null) {
                // 用户发起订单
                storageProcurementOrder.setOrderStatus(OrderType.START_ORDER.getValue());

                // 给被采购方插入系统消息并极光推送
                providerUser = storageUserMapper.selectStorageUserById(storageProcurementOrder.getProvideUserId());
                if (providerUser == null) {
                    return new ServiceResponse<>(false, null, "被采购方账号不存在,请核实重新发起采购");
                }
                title = String.format("您有一条待确认采购订单,订单号：%s 等待您的确认,请前往查看", storageProcurementOrder.getOrderCode());
                noticeMessage = new StorageNoticeMessage(providerUser.getId(), providerUser.getPhone(), storageProcurementOrder.getGoodsContent(), title);
                storageNoticeMessageMapper.insertStorageNoticeMessage(noticeMessage);
                sendNotice(storageProcurementOrder, providerUser.getPhone(), title, storageProcurementOrder.getGoodsContent(), noticeMessage.getId());
            }
            // 新增订单
            storageProcurementOrderMapper.insertStorageProcurementOrder(storageProcurementOrder);

            if (storageProcurementOrder.getOrderStatus() == OrderType.PROVIDER_ACCEPT.getValue()) {
                // 上级发货订单 - 减去相应的库存
                StorageProcurementOrder oldOrder = storageProcurementOrderMapper.selectStorageProcurementOrderById(storageProcurementOrder.getId());

                // 当前被采购方确定完成 - 将被采购方对应的库存数据量减去采购的数据量
                ServiceResponse<Boolean> reduceResponse = reduceOrderGoodsNumberFromProvider(oldOrder);
                if (!reduceResponse.isSuccess()) {
                    return new ServiceResponse<>(false, oldOrder, reduceResponse.getError());
                }

                if (oldOrder.getApplicationType() == OwnerType.SHOP.getValue()) {
                    applicationUser = storageUserMapper.selectStorageUserByShopIdRole(oldOrder.getApplicationUserId(), RoleType.SHOW_LEADER.getValue());
                } else if (oldOrder.getApplicationType() == OwnerType.AGENT.getValue()) {
                    applicationUser = storageUserMapper.selectStorageUserById(oldOrder.getApplicationUserId());
                }

                if (applicationUser != null) {
                    // 给采购方推送上级发货极光消息
                    title = String.format("您有一条待确认的上级发货订单,订单号：%s 等待您的确认,请前往查看", storageProcurementOrder.getOrderCode());
                    noticeMessage = new StorageNoticeMessage(applicationUser.getId(), applicationUser.getPhone(), storageProcurementOrder.getGoodsContent(), title);
                    storageNoticeMessageMapper.insertStorageNoticeMessage(noticeMessage);
                    sendNotice(oldOrder, applicationUser.getPhone(), title, oldOrder.getGoodsContent(), noticeMessage.getId());
                }
            }
        }
        return new ServiceResponse<>(true, storageProcurementOrderMapper.selectStorageProcurementOrderById(storageProcurementOrder.getId()), null);
    }

    private void sendNotice(StorageProcurementOrder order, String phone, String title, String detail, Long msgId) {
        Gson gson = GsonUtil.getGson();
        List<StorageProduct> storageProducts = gson.fromJson(order.getGoodsContent(), new TypeToken<List<StorageProduct>>() {}.getType());
        if (storageProducts == null || storageProducts.size() == 0) {
            return;
        }
        storageProducts.stream().forEach(product -> GoodsConvertUtils.changeForAndriod(product));
        JiGuangPushUtil.pushNotice(phone, title, detail, msgId);
    }

    private String getOrderCode() {
        String date = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String rannum = RandomStringUtils.randomNumeric(4);
        return date + rannum;
    }

    /**
     * 恢复供货商已确认订单减掉的库存数据量
     *
     * @param order
     * @return
     */
    private ServiceResponse<Boolean> revokeProviderStockNum(StorageProcurementOrder order) {
        // 供货商
        Gson gson = GsonUtil.getGson();
        List<StorageProduct> storageProducts = gson.fromJson(order.getGoodsContent(), new TypeToken<List<StorageProduct>>() {
        }.getType());

        for (StorageProduct product : storageProducts) {
            StorageProduct sourceProduct = storageProductMapper.selectStorageProductById(product.getId());
            List<StorageGoods> storageGoods = product.getGoods();
            Integer productRevokeStockNum = 0;
            for (StorageGoods goods : storageGoods) {
                // 根据采购时候的单品id查询单品对象
                StorageGoods sourceGoods = storageGoodsMapper.selectStorageGoodsById(goods.getId());
                sourceGoods.setStockNum(sourceGoods.getStockNum() + goods.getStockNum());
                storageGoodsMapper.updateStorageGoods(sourceGoods);
                productRevokeStockNum += goods.getStockNum().intValue();
            }

            sourceProduct.setTotalGoodsNum(sourceProduct.getTotalGoodsNum() + productRevokeStockNum);
            storageProductMapper.updateStorageProduct(sourceProduct);
        }

        return new ServiceResponse<>(true, null, null);
    }

    /**
     * 自动入库采购商品到采购方库存中
     *
     * @param order
     * @return
     */
    private ServiceResponse<Boolean> autoInsertProcurementUserStock(StorageUser currUser, StorageProcurementOrder order) {

        // 解析出订单中采购的商品
        Gson gson = GsonUtil.getGson();
        List<StorageProduct> storageProducts = gson.fromJson(order.getGoodsContent(), new TypeToken<List<StorageProduct>>() {
        }.getType());

        for (StorageProduct product : storageProducts) {
            // 判断当前采购商品是否已经存在采购方商品列表里面 - 判断依据商品编码 - 如果是是店铺采购那么当前操作用户是代理商所以要区分开
            Long operationUserId = RoleType.getOperationUserId(currUser.getRole(), currUser.getId(), currUser.getShopId());
            Integer ownerType = RoleType.getOwnerType(currUser.getRole());
            if (order.getApplicationType() == OwnerType.SHOP.getValue()) {
                operationUserId = order.getApplicationUserId();
                ownerType = order.getApplicationType();
            }

            if (operationUserId == null) {
                return new ServiceResponse<>(false, null, "当前用户没有操作权限");
            }

            // 查询出原有商品关联图片
            StorageImage imageCondition = new StorageImage();
            imageCondition.setLinkProductId(product.getId());
            List<StorageImage> images = storageImageMapper.selectStorageImageList(imageCondition);

            StorageProduct existProduct = storageProductMapper.selectStorageProduct(operationUserId, ownerType, product.getProductSpuCode());
            if (existProduct != null) {
                List<StorageGoods> storageGoods = product.getGoods();
                if (storageGoods.isEmpty()) {
                    continue;
                }

                storageGoods.forEach(goods -> autoInsertGoods(goods, existProduct));
                // 更新产品的总库存和实时库存
                existProduct.setTotalGoodsNum(existProduct.getTotalGoodsNum() + product.getTotalGoodsNum());
                existProduct.setRealTimeGoodsNum(existProduct.getRealTimeGoodsNum() + product.getRealTimeGoodsNum());
                storageProductMapper.updateStorageProduct(existProduct);
            } else {
                // 插入 product
                product.setId(null);
                product.setBrandId(null);
                product.setCategoryId(null);
                product.setStatus(ProductStatusType.IN_SELL.getValue());
                product.setCreateUserId(operationUserId);
                product.setOwnerType(ownerType);
                product.setCreateTime(new Date());
                product.setModifyTime(new Date());
                storageProductMapper.insertStorageProduct(product);

                // 插入关联图片
                if (!images.isEmpty()) {
                    for (StorageImage image : images) {
                        image.setLinkProductId(product.getId());
                        image.setId(null);
                        image.setCreateTime(new Date());
                        image.setModifyTime(new Date());
                        storageImageMapper.insertStorageImage(image);
                    }
                }

                List<StorageGoods> storageGoods = product.getGoods();
                if (storageGoods.isEmpty()) {
                    continue;
                }
                storageGoods.forEach(goods -> autoInsertGoods(goods, product));
            }
        }

        return new ServiceResponse<>(true, null, null);
    }

    /**
     * 单品自动入库
     *
     * @param goods
     * @param existProduct
     * @return
     */
    private boolean autoInsertGoods(StorageGoods goods, StorageProduct existProduct) {
        // 思路：取出当前要入库的单品的属性详情 与 原有已经存在的单品的属性详情做完全匹配，如果匹配上了那就直接做库存数量的叠加，否则认为是新单品直接新增
        List<StorageGoods> existGoodsArr = storageGoodsMapper.selectStorageGoodsByProductId(existProduct.getId());
        if (existGoodsArr == null || existGoodsArr.size() == 0) {

            // 为当前产品新增对应的单品
            goods.setId(null);
            goods.setProductId(existProduct.getId());
            goods.setCreateUserId(existProduct.getCreateUserId());
            goods.setOwnerType(existProduct.getOwnerType());
            goods.setPurchasePrice(goods.getPurchasePrice());
            goods.setTradePrice(goods.getTradePrice());
            goods.setRetailPrice(goods.getRetailPrice());
            storageGoodsMapper.insertStorageGoods(goods);
            return true;
        }

        // 进行比对
        StorageGoods existGoods = existGoodsArr.stream()
                .filter(item -> checkPropertiesDetailMatch(item, goods))
                .findFirst().orElse(null);
        if (existGoods != null) {
            // 数量叠加
            existGoods.setStockNum(existGoods.getStockNum() + goods.getStockNum());
            storageGoodsMapper.updateStorageGoods(existGoods);
        } else {
            // 为当前产品新增对应的单品
            goods.setId(null);
            goods.setProductId(existProduct.getId());
            goods.setCreateUserId(existProduct.getCreateUserId());
            goods.setOwnerType(existProduct.getOwnerType());
            goods.setPurchasePrice(goods.getPurchasePrice());
            goods.setTradePrice(goods.getTradePrice());
            goods.setRetailPrice(goods.getRetailPrice());
            storageGoodsMapper.insertStorageGoods(goods);
        }
        return true;
    }

    /**
     * 比对属性详情,进货价,批发价,零售价 是否相等
     * <p>
     * eg: [{"尺码":"35"}]
     *
     * @param existGoods
     * @param newGoods
     * @return
     */
    private boolean checkPropertiesDetailMatch(StorageGoods existGoods, StorageGoods newGoods) {
        if (StringUtils.isBlank(existGoods.getPropertiesDetail()) || StringUtils.isBlank(newGoods.getPropertiesDetail())) {
            return false;
        }

        JSONArray existArr = JSONArray.parseArray(existGoods.getPropertiesDetail());
        JSONArray newArr = JSONArray.parseArray(newGoods.getPropertiesDetail());
        if (existArr.size() != newArr.size()) {
            return false;
        } else if (!existArr.equals(newArr)) {
            return false;
        } else if (existGoods.getPurchasePrice().intValue() != newGoods.getPurchasePrice().intValue()) {
            return false;
        } else if (existGoods.getTradePrice().intValue() != newGoods.getTradePrice().intValue()) {
            return false;
        } else if (existGoods.getRetailPrice().intValue() != newGoods.getRetailPrice().intValue()) {
            return false;
        }
        return true;
    }

    /**
     * 当前订单最终确定完成 - 将被采购方对应的库存数据量减去采购的数据量
     *
     * @param order
     * @return
     */
    private ServiceResponse<Boolean> reduceOrderGoodsNumberFromProvider(StorageProcurementOrder order) {
        Gson gson = GsonUtil.getGson();
        List<StorageProduct> storageProducts = gson.fromJson(order.getGoodsContent(), new TypeToken<List<StorageProduct>>() {
        }.getType());
        StringBuilder message = new StringBuilder();

        for (StorageProduct product : storageProducts) {
            if (product.getGoods() == null || product.getGoods().size() == 0) {
                continue;
            }
            StorageProduct sourceProduct = storageProductMapper.selectStorageProductById(product.getId());
            for (StorageGoods goods : product.getGoods()) {
                // 根据商品id查询被采购代理商当前单品库存量 - 被采购量 = 最终剩余量
                StorageGoods sourceGoods = storageGoodsMapper.selectStorageGoodsById(goods.getId());
                if (sourceGoods == null) {
                    continue;
                }

                // 更新商品的库存量
                Long productRemainingStockNum = sourceProduct.getRealTimeGoodsNum() - goods.getStockNum().intValue();
                if (productRemainingStockNum < 0) {
                    message.append(String.format("商品数量不足: 商品id=[%s] 商品库存=[%s] 当前采购数量=[%s]", sourceProduct.getId(),
                            sourceProduct.getTotalGoodsNum(), productRemainingStockNum));
                    continue;
                }
                sourceProduct.setRealTimeGoodsNum(productRemainingStockNum);

                // 更新单品库存量
                Long goodsRemainingStockNum = sourceGoods.getStockNum() - goods.getStockNum();
                if (goodsRemainingStockNum < 0) {
                    message.append(String.format("单品数量不足：单品id=[%s] 单品库存=[%s] 当前采购数量=[%s];",
                            sourceGoods.getId(), sourceGoods.getStockNum(), goods.getStockNum()));
                    continue;
                }
                sourceGoods.setStockNum(goodsRemainingStockNum);
                storageGoodsMapper.updateStorageGoods(sourceGoods);

                GoodsConvertUtils.checkWarning(sourceGoods, sourceProduct);
            }

            storageProductMapper.updateStorageProduct(sourceProduct);
        }
        if (StringUtils.isNotBlank(message.toString())) {
            return new ServiceResponse<>(false, null, message.toString());
        }
        return new ServiceResponse<>(true, null, null);
    }

    /**
     * 计算采购方和供货方之间的账目结算
     *
     * @param user
     * @param order
     * @return
     */
    private ServiceResponse<Boolean> calculateMoney(StorageUser user, StorageProcurementOrder order) {
        StorageUserAgent upAgent = null;
        StorageUserAgent downAgent = null;

        if (order.getApplicationType() == OwnerType.AGENT.getValue()) {
            // 下级代理商有机会点击order_success
            upAgent = storageUserAgentMapper.selectUserAgent(order.getProvideUserId(), order.getApplicationUserId(), UserAndAgentLevelType.DOWN.getValue(), OwnerType.AGENT.name());
            downAgent = storageUserAgentMapper.selectUserAgent(order.getApplicationUserId(), order.getProvideUserId(), UserAndAgentLevelType.UP.getValue(), OwnerType.AGENT.name());
        } else if (order.getApplicationType() == OwnerType.SHOP.getValue()) {
            // 店铺向代理商采购 代理商直接同意
            upAgent = storageUserAgentMapper.selectUserAgent(order.getProvideUserId(), order.getApplicationUserId(), UserAndAgentLevelType.DOWN.getValue(), OwnerType.SHOP.name());
            downAgent = storageUserAgentMapper.selectUserAgent(order.getApplicationUserId(), order.getProvideUserId(), UserAndAgentLevelType.UP.getValue(), OwnerType.SHOP.name());
        }

        if (downAgent == null || upAgent == null) {
            String error = RoleType.isWorker(user.getRole()) ? "店铺与代理商关联关系异常" : "代理商关联关系异常";
            return new ServiceResponse<>(false, null, error);
        }

        BigDecimal downPaymentMoney = downAgent.getPaymentMoney() == null ? new BigDecimal(0) : downAgent.getPaymentMoney();
        BigDecimal upPaymentMoney = upAgent.getPaymentMoney() == null ? new BigDecimal(0) : upAgent.getPaymentMoney();

        // 上下级账目是否准匹配
        BigDecimal result = downPaymentMoney.add(upPaymentMoney);
        if (!result.equals(new BigDecimal(0))) {
            return new ServiceResponse<>(false, null, "当前上下级账目异常");
        }

        // 差价 = 总价 - 实际付款
        BigDecimal diff = order.getOrderTotalPrice().subtract(order.getActualPaymentAmount());
        downAgent.setPaymentMoney(downPaymentMoney.subtract(diff));
        upAgent.setPaymentMoney(upPaymentMoney.add(diff));

        // 更新欠款
        storageUserAgentMapper.updateStorageUserAgent(downAgent);
        storageUserAgentMapper.updateStorageUserAgent(upAgent);

        // 添加付款记录
        StorageAccountRecord record = new StorageAccountRecord();
        record.setUserId(order.getApplicationUserId());
        record.setAgentId(order.getProvideUserId());
        record.setMoney(order.getActualPaymentAmount());
        record.setSource(AccountRecordType.ORDER.name());
        int type = order.getApplicationType() == OwnerType.SHOP.getValue() ? OwnerType.SHOP.getValue() : OwnerType.AGENT.getValue();
        record.setOrderCode(order.getOrderCode());
        record.setType(type);
        record.setRemark(order.getRemark());
        storageAccountRecordMapper.insertStorageAccountRecord(record);
        return new ServiceResponse<>(true, null, null);
    }

    /**
     * 删除采购/订购 订单对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteStorageProcurementOrderByIds(String ids) {
        return storageProcurementOrderMapper.deleteStorageProcurementOrderByIds(Convert.toStrArray(ids));
    }

    /**
     * 代理商给下级直接发货
     *
     * @param storageUser
     * @param procurementOrder
     * @return
     */
    @Override
    public ServiceResponse<StorageProcurementOrder> agentSendOrder(StorageUser storageUser, StorageProcurementOrder procurementOrder) {
        String error = null;
        StorageUser applicationUser = null;
        if (procurementOrder.getApplicationUserId() == null) {
            error = "下级用户不能为空";
        } else if ((applicationUser = storageUserMapper.selectStorageUserById(procurementOrder.getApplicationUserId())) == null) {
            error = "下级用户不存在";
        }

        if (StringUtils.isNotBlank(error)) {
            return new ServiceResponse<>(false, null, error);
        }

        Long applicationUserId = RoleType.getOperationUserId(applicationUser.getRole(), applicationUser.getId(), applicationUser.getShopId());
        Integer applicationType = RoleType.getOwnerType(applicationUser.getRole());
        procurementOrder.setOrderStatus(OrderType.PROVIDER_ACCEPT.getValue());
        procurementOrder.setApplicationUserId(applicationUserId);
        procurementOrder.setApplicationType(applicationType);
        procurementOrder.setProcurementType(ProcurementType.AGENT_SEND.getValue());

        storageProcurementOrderMapper.insertStorageProcurementOrder(procurementOrder);
        if (procurementOrder.getId() != null) {
            procurementOrder = storageProcurementOrderMapper.selectStorageProcurementOrderById(procurementOrder.getId());
        }
        return new ServiceResponse<>(true, procurementOrder, null);
    }
}
